/**
 * Created with JetBrains WebStorm.
 * User: Zuobai
 * Date: 13-7-30
 * Time: 上午9:36
 * To change this template use File | Settings | File Templates.
 */

(function () {
	var TextBox = Z.element.TextBox;
	var Button = Z.element.Button;
	var Label = Z.element.Label;
	var Event = Z.Event;

	var NumberPercent = {
		Number : 0,
		Percent : 1,
		Empty : 2
	};

	// 遍历对象
	function loopObj( obj, block ) {
		for ( var key in obj ) {
			block( key, obj[key] );
		}
	}

	// 判断一个字符串是整数或者百分数,如果都不是,返回null
	function numberOrPercent( num ) {
		var result = 0;
		var digits = [];
		var i = 0, len = num.length, pow = 1;
		var type = NumberPercent.Number;

		if ( num === "" ) {
			return {
				type : NumberPercent.Empty
			};
		}


		for ( ; i != len; ++i ) {
			var ch = num.charCodeAt( i );
			//  读字符
			if ( ch >= 0x30 && ch <= 0x39 ) {
				digits.push( ch - 0x30 );
			}
			// 如果读到了非数字,根据当前是否读到了数字进行选择,如果读到了数字,那么可以接受百分号
			// 否则返回null
			else {
				if ( digits.length !== 0 ) {
					if ( ch === 0x25 ) {
						type = NumberPercent.Percent;
						++i;
						break;
					}
					else {
						return null;
					}
				}
			}
		}

		// 如果百分号后面还有内容,返回null
		if ( i !== len ) {
			return null;
		}

		// 计算数字
		for ( i = digits.length - 1; i >= 0; --i ) {
			result += digits[i] * pow;
			pow *= 10;
		}

		if ( type === NumberPercent.Percent && result > 100 ) return null;

		return {
			type : type,
			number : result
		}
	}

	// 组合一个Label和一个Box
	function LabelTextBox( area, left, textBoxOffset, top, label, textBoxWidth ) {
		Label( area, {
			left : left,
			top : top + 3,
			text : label
		} );

		return TextBox( area, {
			left : left + textBoxOffset,
			top : top,
			width : textBoxWidth
		} );
	}

	// 创建一个定位尺寸组,对于任意的定位尺寸组来说,仅有两个定位尺寸能起作用
	function positionSizeGroup( area, positionSizeArr, left, top ) {
		var curTop = 0; // 当前的高度
		var value = {}, oldValue; // 结果集
		var validValueCount = 0; // 合法数值计数

		// change事件,当该组数值由合法切换到不合法,或者由不合法切换到合法时触发
		var changeEvent = Event();

		// 根据计数值决定是否触发事件
		function change( oldValue, value ) {
			if ( value === 2 ) {
				changeEvent.trig( true );
			}
			else if ( oldValue === 2 ) {
				changeEvent.trig( false );
			}
		}

		loopObj( positionSizeArr, function ( positionSizeName ) {
			var text = LabelTextBox( area, left, 65, top + curTop, positionSizeName + ":", 70 );
			curTop += 35;
			text.onInput( function () {
					// 获取数值,根据数值是否合法修改text框的颜色
					var num = numberOrPercent( text.value() );
					oldValue = value[positionSizeName];
					if ( num === null || num.type === NumberPercent.Empty ) {
						text.background_color( num === null ? "orange" : "white" );
						value[positionSizeName] = undefined;
						if ( oldValue !== undefined ) {
							change( validValueCount, validValueCount - 1 );
							--validValueCount;
						}
					}
					else {
						text.background_color( "white" );
						value[positionSizeName] = num;
						if ( oldValue === undefined ) {
							change( validValueCount, validValueCount + 1 );
							++validValueCount;
						}
					}
				}
			);
		} );

		return {
			onChange : function ( event ) {
				changeEvent.regist( event );
			},
			success : function () {
				return validValueCount == 2;
			},
			value : function () {
				var validValue = [];
				var validRatio = [];

				// 取出合法项
				if ( validValueCount == 2 ) {
					loopObj( value, function ( key, item ) {
						if ( item !== undefined ) {
							validRatio.push( positionSizeArr[key] );
							validValue.push( { type : item.type, number : item.number} );
						}
					} );

					// 取值
					var a1 = validRatio[0][0], a2 = validRatio[0][1], a3 = validRatio[0][2];
					var b1 = validRatio[1][0], b2 = validRatio[1][1], b3 = validRatio[1][2];
					var M = validValue[0], N = validValue[1];

					return {
						adjust : function ( P ) {
							function caculate( val ) {
								return val.type === NumberPercent.Number ? val.number : val.number * P / 100;
							}

							var m = caculate( M ), n = caculate( N );

							return {
								S : Math.floor( (b2 * m - a1 * b2 * P - a2 * n + a2 * b1 * P) / (a3 * b2 - a2 * b3) ),
								O : Math.floor( (b3 * m - a1 * b3 * P - a3 * n + a3 * b1 * P) / (a2 * b3 - a3 * b2) )
							}
						},
						resize : function ( P, O, S ) {
							function caculate( val, type ) {
								return type === NumberPercent.Number ? val : Math.floor( val / P * 100 );
							}

							M.number = caculate( a1 * P + a2 * O + a3 * S, M.type );
							N.number = caculate( b1 * P + b2 * O + b3 * S, N.type );
						}
					}
				}
				else {
					return null;
				}
			}
		};
	}

	function ratio( a1, a2, a3 ) {
		return [a1, a2, a3];
	}

	onLoad( function ( body ) {
		// 输入区域
		var inputArea = body.area( {
			height : 210,
			width : 400,
			background_color : "white"
		} );

		var group1 = positionSizeGroup( inputArea, {
			"left" : ratio( 0, 1, 0 ),
			"right" : ratio( 1, -1, -1 ),
			"width" : ratio( 0, 0, 1 ),
			"x中线" : ratio( -0.5, 1, 0.5 )
		}, 10, 10 );
		var group2 = positionSizeGroup( inputArea, {
			"top" : ratio( 0, 1, 0 ),
			"bottom" : ratio( 1, -1, -1 ),
			"height" : ratio( 0, 0, 1 ),
			"y中线" : ratio( -0.5, 1, 0.5 )
		}, 170, 10 );

		var adjustSelect = Z.element.Select( inputArea, {
			left : 10,
			top : 150,
			items : [
				{value : "y", text : "总是自适应"},
				{value : "n", text : "仅初始"}
			]
		} );

		var priorSelect = Z.element.Select( inputArea, {
			left : 120,
			top : 150,
			items : [
				{value : "y", text : "尺寸优先"},
				{value : "n", text : "位置优先"}
			]
		} );

		var colors = ["red", "yellow", "blue", "green", "purple", "orange"];
		var button = Button( inputArea, {
			text : "绘制",
			left : 10,
			top : 180,
			disabled : true,
			onClick : function () {
				var isAdjust = adjustSelect.value() === "y";
				var isSizePrior = priorSelect.value() === "y";
				var xInsts = group1.value();
				var yInsts = group2.value();

				var rect = body.area( {
					background_color : colors[Math.floor( Math.random() * 100 ) % 6]
				} );

				// 拖动
				rect.onMousedown( function ( event ) {
					var pWidth = body.offsetWidth(), pHeight = body.offsetHeight();
					var inX = event.offsetX, inY = event.offsetY;
					event.preventDefault();

					event.onMousemove( function ( event ) {
						var curX = event.pageX - inX, curY = event.pageY - inY;
						// 防止超出屏幕
						if ( curX < 0 ) curX = 0;
						if ( curY < 0 ) curY = 0;
						if ( curX + rect.offsetWidth() > body.offsetWidth() ) curX = body.offsetWidth() - rect.offsetWidth();
						if ( curY + rect.offsetHeight() > body.offsetHeight() ) curY = body.offsetHeight() - rect.offsetHeight();

						event.preventDefault();
						rect.left( curX );
						rect.top( curY );
					} );

					event.onMouseup( function () {
						if ( isAdjust ) {
							xInsts.resize( pWidth, rect.left(), rect.offsetWidth() );
							yInsts.resize( pHeight, rect.top(), rect.offsetHeight() );
						}
					} );
				} );

				if ( isAdjust ) {
					body.onResize( function () {
						adjust();
					} );
				}
				else {
				}

				// 尺寸器
				var resizer = rect.area( {
					width : 10,
					height : 10,
					cursor : "nw-resize",
					// 尺寸变化
					onMousedown : function ( event ) {
						var pWidth = body.offsetWidth(), pHeight = body.offsetHeight();
						event.preventDefault();
						event.stopPropagation(); // 阻止冒泡,也就是说,不会触发拖动事件

						var inX = event.offsetX + resizer.left(), inY = event.offsetY + resizer.top();
						var oldX = event.pageX, oldY = event.pageY;

						event.onMousemove( function ( event ) {
							rect.width( Math.max( event.pageX - oldX + inX, 20 ) );
							rect.height( Math.max( event.pageY - oldY + inY, 20 ) );
							resizer.top( rect.offsetHeight() - 10 );
							resizer.left( rect.offsetWidth() - 10 );
							if ( isAdjust ) {
								xInsts.resize( pWidth, rect.left(), rect.offsetWidth() );
								yInsts.resize( pHeight, rect.top(), rect.offsetHeight() );
							}
						} );
					}
				} );

				// 自适应宽高
				function adjust() {
					var xPosSize = xInsts.adjust( body.offsetWidth() );
					var yPosSize = yInsts.adjust( body.offsetHeight() );

					if ( xPosSize.O + xPosSize.S > body.offsetWidth() ) {
						if ( isSizePrior ) {
							xPosSize.S = Math.min( body.offsetWidth(), xPosSize.S );
							xPosSize.O = body.offsetWidth() - xPosSize.S;
						}
						else {
							xPosSize.S = body.offsetWidth() - xPosSize.O;
						}
					}

					if ( yPosSize.O + yPosSize.S > body.offsetHeight() ) {
						if ( isSizePrior ) {
							yPosSize.S = Math.min( body.offsetHeight(), yPosSize.S );
							yPosSize.O = body.offsetHeight() - yPosSize.S;
						}
						else {
							yPosSize.S = body.offsetHeight() - yPosSize.O;
						}
					}

					rect.left( xPosSize.O );
					rect.width( xPosSize.S );
					rect.top( yPosSize.O );
					rect.height( yPosSize.S );
					resizer.top( rect.offsetHeight() - 10 );
					resizer.left( rect.offsetWidth() - 10 );
				}

				adjust();
			}
		} );

		group1.onChange( function ( success ) {
			button.disabled( !(success && group2.success()) );
		} );
		group2.onChange( function ( success ) {
			button.disabled( !(success && group1.success()) );
		} );
	} );
})
	();

